package com.cn.delan.core.util;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串工具类
 * @author BingGo
 *
 */
public class StringUtil {
	/** A table of hex digits */
	private static final char[] hexDigit = { '0', '1', '2', '3', '4', '5', '6',
			'7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
	private static char toHex(int nibble) {
		return hexDigit[(nibble & 0xF)];
	}
	/**
	 * 将字符串转换为对应的\\uxxxx格式
	 * @param str 需要转换的字符串
	 * @return 转换后的字符串
	 */
	public static String saveConvert(String str){
		return saveConvert(str,true,true);
	}
	private static String saveConvert(String theString, boolean escapeSpace,boolean escapeUnicode) {
		int len = theString.length();
		int bufLen = len * 2;
		if (bufLen < 0) {
			bufLen = Integer.MAX_VALUE;
		}
		StringBuffer outBuffer = new StringBuffer(bufLen);

		for (int x = 0; x < len; x++) {
			char aChar = theString.charAt(x);
			// Handle common case first, selecting largest block that
			// avoids the specials below
			if ((aChar > 61) && (aChar < 127)) {
				if (aChar == '\\') {
					outBuffer.append('\\');
					outBuffer.append('\\');
					continue;
				}
				outBuffer.append(aChar);
				continue;
			}
			switch (aChar) {
			case ' ':
				if (x == 0 || escapeSpace)
					outBuffer.append('\\');
				outBuffer.append(' ');
				break;
			case '\t':
				outBuffer.append('\\');
				outBuffer.append('t');
				break;
			case '\n':
				outBuffer.append('\\');
				outBuffer.append('n');
				break;
			case '\r':
				outBuffer.append('\\');
				outBuffer.append('r');
				break;
			case '\f':
				outBuffer.append('\\');
				outBuffer.append('f');
				break;
			case '=': // Fall through
			case ':': // Fall through
			case '#': // Fall through
			case '!':
				outBuffer.append('\\');
				outBuffer.append(aChar);
				break;
			default:
				if (((aChar < 0x0020) || (aChar > 0x007e)) & escapeUnicode) {
					outBuffer.append('\\');
					outBuffer.append('u');
					outBuffer.append(toHex((aChar >> 12) & 0xF));
					outBuffer.append(toHex((aChar >> 8) & 0xF));
					outBuffer.append(toHex((aChar >> 4) & 0xF));
					outBuffer.append(toHex(aChar & 0xF));
				} else {
					outBuffer.append(aChar);
				}
			}
		}
		return outBuffer.toString();
	}
	/**
	 * 将\\uxxxx格式的字符串转换成为普通能够阅读的字符串
	 * @param str \\uxxxx格式的字符串
	 * @return 能够阅读的字符串ascii
	 */
	public static String loadConvert(String str){
		String t = str.replaceAll(";", "");
		t = t.replaceAll("&#x", "\\\\u");
		if(t.startsWith("&#")){
			t = toHex(t);
		}
		char[] chars = t.toCharArray();
		return loadConvert(chars,0,chars.length,null);
	}
	/**
	 * 将字符串中的10进制表示转换为16进制表示
	 * @param str
	 * @return
	 */
	private static String toHex(String str){
		String chars[] = str.split("&#");
		StringBuffer sb = new StringBuffer();
		for(String s:chars){
			if(!s.equals("")){
				sb.append("\\u");
				String hex = s;
				String after = "";
				if(s.length()>5){
					hex = s.substring(0,5);
					after = s.substring(5);
				}
				sb.append(Integer.toHexString(Integer.parseInt(hex))+after);
			}
		}
		return sb.toString();
	}
    private static String loadConvert (char[] in, int off, int len, char[] convtBuf) {
        if (convtBuf==null || convtBuf.length < len) {
            int newLen = len * 2;
            if (newLen < 0) {
	        newLen = Integer.MAX_VALUE;
	    } 
	    convtBuf = new char[newLen];
        }
        char aChar;
        char[] out = convtBuf; 
        int outLen = 0;
        int end = off + len;

        while (off < end) {
            aChar = in[off++];
            if (aChar == '\\') {
                aChar = in[off++];   
                if(aChar == 'u') {
                    // Read the xxxx
                    int value=0;
		    for (int i=0; i<4; i++) {
		        aChar = in[off++];  
		        switch (aChar) {
		          case '0': case '1': case '2': case '3': case '4':
		          case '5': case '6': case '7': case '8': case '9':
		             value = (value << 4) + aChar - '0';
			     break;
			  case 'a': case 'b': case 'c':
                          case 'd': case 'e': case 'f':
			     value = (value << 4) + 10 + aChar - 'a';
			     break;
			  case 'A': case 'B': case 'C':
                          case 'D': case 'E': case 'F':
			     value = (value << 4) + 10 + aChar - 'A';
			     break;
			  default:
                              throw new IllegalArgumentException(
                                           "Malformed \\uxxxx encoding.");
                        }
                     }
                    out[outLen++] = (char)value;
                } else {
                    if (aChar == 't') aChar = '\t'; 
                    else if (aChar == 'r') aChar = '\r';
                    else if (aChar == 'n') aChar = '\n';
                    else if (aChar == 'f') aChar = '\f'; 
                    out[outLen++] = aChar;
                }
            } else {
	        out[outLen++] = (char)aChar;
            }
        }
        return new String (out, 0, outLen);
    }
	/**
	 * 将字符串数组连接在一起,采用分号分隔
	 * @param stringArrays 字符串数组
	 * @return 返回连接后的字符串. 
	 */
	public static String join(String []stringArrays){
		if(stringArrays==null)
			return null;
		StringBuffer buffer = new StringBuffer();
		for(String s:stringArrays){
			if(s==null || s.equals("")){
				continue;
			}
			if(!buffer.toString().equals(""))
				buffer.append(";");
			buffer.append(s);
		}
		return buffer.toString();
	}
	/**
	 * 将字符串数组连接在一起,采用分隔符分隔
	 * @param stringArrays 字符串数组
	 * @param separator 分隔符
	 * @return 返回连接后的字符串
	 */
	public static String join(String []stringArrays,String separator){
		if(stringArrays==null)
			return null;
		StringBuffer buffer = new StringBuffer();
		for(String s:stringArrays){
			if(s==null || s.equals("")){
				continue;
			}
			if(!buffer.toString().equals("")){
				if(separator!=null){
					buffer.append(separator);
				}
			}
			buffer.append(s);
		}
		return buffer.toString();
	}
	/**
	 * 判断字符串是否为空，包括回车、换行、tab键都属于空字符串，正则表达式\s所匹配的字符串皆属于空字符串
	 * @param str 需要判断的字符串
	 * @return 为空则返回true，否则返回false
	 */
	public static boolean isEmpty(String str){
		return (str==null || str.replaceAll("\\s", "").equals(""));
	}
	/**
	 * 颠倒字符串
	 * @param str 要颠倒的字符串
	 * @return 颠倒后的字符串
	 */
	public static String reverse(String str){
		if(str==null){
			return null;
		}
		StringBuffer buffer = new StringBuffer();
		for(int i=0;i<str.length();i++){
			buffer.insert(0, str.charAt(i));
		}
		return buffer.toString();
	}
	/**
	 * 对指定文本进行正则表达式匹配
	 * @param str 进行匹配的文本
	 * @param regex 正则表达式
	 * @return 正则表达式匹配后的信息列表。list中的字符串数组是正则表达式匹配的各个组，下标0时为整个匹配的字符串。
	 */
	public static List<String []> matcher(String str,String regex){
		if(str==null || regex==null){
			return null;
		}
		ArrayList<String[]> list = new ArrayList<String[]>();
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		while(matcher.find()){
			String []params = new String[matcher.groupCount()+1];
			for(int i=0;i<params.length;i++){
				params[i] = matcher.group(i);
			}
			list.add(params);
		}
		return list;
	}
	//TODO 此类需要进一步完善包括常用的字符串操作及验证
    public static void main(String args[]){
		String s1 = "&#x5929;&#x6d25;&#x5206;&#x516c;&#x53f8;";
		String s2 = "\u5929\u6d25\u5206\u516c\u53f8";
		String s3 = "&#27979;&#35797;&#20869;&#23481;&lt;B&gt;&#26631;&#39064;&lt;/B&gt;";
		System.out.println(StringUtil.loadConvert(s1));
		System.out.println(StringUtil.loadConvert(s2));
		System.out.println(StringUtil.loadConvert(s3));
		System.out.println(StringUtil.saveConvert("天津分公司"));
    }

}
